// Go作者版权所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package load

import (
	"path/filepath"
	"strings"

	"cmd/go/internal/search"
)

// MatchPackage（pattern，cwd）（p）报告包p是否匹配工作目录cwd中的模式。
func MatchPackage(pattern, cwd string) func(*Package) bool {
	switch {
	case search.IsRelativePath(pattern):
		// 将模式拆分为前导模式自由目录路径
		// （包括所有.和..元素）和最终模式。
		var dir string
		i := strings.Index(pattern, "...")
		if i < 0 {
			dir, pattern = pattern, ""
		} else {
			j := strings.LastIndex(pattern[:i], "/")
			dir, pattern = pattern[:j], pattern[j+1:]
		}
		dir = filepath.Join(cwd, dir)
		if pattern == "" {
			return func(p *Package) bool { return p.Dir == dir }
		}
		matchPath := search.MatchPattern(pattern)
		return func(p *Package) bool {
			// 计算dir的相对路径，看看它是否与模式匹配。
			rel, err := filepath.Rel(dir, p.Dir)
			if err != nil {
				// 无法设置相对-例如，Windows上的驱动器号不同。
				return false
			}
			rel = filepath.ToSlash(rel)
			if rel == ".." || strings.HasPrefix(rel, "../") {
				return false
			}
			return matchPath(rel)
		}
	case pattern == "all":
		return func(p *Package) bool { return true }
	case pattern == "std":
		return func(p *Package) bool { return p.Standard }
	case pattern == "cmd":
		return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
	default:
		matchPath := search.MatchPattern(pattern)
		return func(p *Package) bool { return matchPath(p.ImportPath) }
	}
}
